-- CommentM
-- create By cheny3 Nor/6/2015
-- 评论模块

module("CommentM", package.seeall);

--[[
    本地留存数据结构，只留存当前查看类型的数据
    界面关闭后就清空数据
    topPraiseRecords = { data1, datd2, data3, ……};
    lastestRecords = { data1, data2, ……};
    commentRids = { rid1, rid2, ……};
--]]

-- 本地留存数据
local lastRequestTime  = nil;    -- 上次请求评论时间
local lastestRecords   = {};
local topPraiseRecords = {};
local commentRids      = {};
local requestType      = nil;    -- 上次请求类型
local commentCount     = {};     -- 评论数量本地留存
local commentCountTime = {};     -- 数量更新时间
local MAX_DBA_COUNT    = 10000;  -- 最大存储
local TIME_LIMIT       = 600;    -- 数量更新时间限制
local MAX_SHOW_COUNT   = 99;     -- 按钮上显示的最多评论数量99
local commentLang      = nil;

-- 初始化模块
function init()
    clearLocalRecords();
    commentCountTime = {};
    commentCount = {};
    commentLang = nil;
end

-- 清空所有的数据（重开界面就清空）
function clearLocalRecords()
    lastestRecords = {};
    topPraiseRecords = {};
    commentRids = {};
    requestType = nil;
    lastRequestTime = nil;
end

-- 替换自己发布的帖子的rid
function changeNewPostRid(rid)
    local commentType;
    for index, data in pairs(lastestRecords) do
        if data["rid"] == "0" then
            -- 修改成正确的
            data["rid"] = rid;
            commentType = data["type"];
            table.insert(commentRids, rid);
            break;
        end
    end

    if commentType then
        -- 直接更新数量
        local count;
        if commentCount[commentType] then
            count = math.min(commentCount[commentType] + 1, MAX_DBA_COUNT);
        else
            count = 1;
        end
        updateCommentCount(commentType, count);
    end
end

-- 删除刚才自己插入的帖子
function deleteNewPostComment()
    for index, data in pairs(lastestRecords) do
        if data["rid"] == "0" then
            -- 自己伪造的
            table.remove(lastestRecords, index);
            break;
        end
    end
end

-- 发表帖子
function postNewComment(commentType, content)
    -- 伪造数据
    local curTime  = TimeM.getServerTime();
    local nickname = ME.user.dbase:query("nickname");

    if nick or nickname == "" then
        nickname = getLocStr("anonymous");
    end

    local data = {
        ["rid"]  = "0", -- 伪造的数据，随便给个RID
        ["type"] = commentType,
        ["user_rid"] = ME.user.rid,
        ["nickname"] = nickname;
        ["praise"] = 0,
        ["create_time"] = curTime,
        ["statue"] = 1,
        ["content"] = content,
        ["lang"] = getLang(),
    };

    -- 本地自己加上,插到队头
    table.insert(lastestRecords, 1, data);

    -- 发送指令
    Operation.cmd_post_new_comment(commentType, content);

    -- 发帖时间
    ME.user.dbase:set("last_comment_time", TimeM.getServerTime());
end

-- 点赞帖子
function addPraise(commentType, rids)
    -- 相关数据界面直接加上即可这里不管了

    -- 发送指令
    Operation.cmd_praise_comment(commentType, rids);
end

-- 取消点赞
function cancelPraise(commentType, rids)
    -- 相关数据界面直接扣除即可这里不管了

    -- 发送指令
    Operation.cmd_cancel_praise_comment(commentType, rids);
end

-- 请求点赞前N数据
function requestTopPraiseComment(commentType)
    local data = {};
    data["class"] = "top";
    data["type"] = commentType;

    if requestType ~= commentType then
        topPraiseRecords = {};
    end

    requestType = commentType;

    Operation.cmd_request_bbs_comments(data);

    lastRequestTime = TimeM.getServerTime();
end

-- 请求最新评论数据
function requestLastestComment(commentType, index, size, lang)
    local data = {};
    data["class"] = "lastest";
    data["type"] = commentType;
    data["index"] = index;
    data["size"] = size;
    data["lang"] = lang or "";

    if requestType ~= commentType then
        lastestRecords = {};
    end

    requestType = commentType;

    Operation.cmd_request_bbs_comments(data);
end

-- 点赞前N数据到达
function receiveTopPraiseComments(commentType, records)
    if not requestType or requestType ~= commentType then
        -- 不是正在等待的数据
        return;
    end

    if #records <= 0 then
        -- 没有数据
        EventMgr.fire(event.BBS_COMMENTS_ALREADY, { ["class"] = "top", });
        return;
    end

    -- 直接全部替换掉
    topPraiseRecords = records;

    for i = 1, #records do
        table.insert(commentRids, records[i]["rid"]);
    end

    -- 抛出事件
    EventMgr.fire(event.BBS_COMMENTS_ALREADY, { ["class"] = "top", ["has_data"] = true});
end

-- 最新评论数据到达
function receiveLastestComments(commentType, records)
    if not requestType or requestType ~= commentType then
        -- 不是正在等待的数据
        return;
    end

    if #records <= 0 then
        -- 没有更多数据了
        EventMgr.fire(event.BBS_COMMENTS_ALREADY, { ["class"] = "lastest", });
        return;
    end

    local has_data = false;
    for i = 1, #records do
        -- 避免重复
        if table.indexOf(commentRids, records[i]["rid"]) == -1 then
            table.insert(lastestRecords, records[i]);
            table.insert(commentRids, records[i]["rid"]);
            has_data = true;
        end
    end

    -- 抛出事件
    EventMgr.fire(event.BBS_COMMENTS_ALREADY, { ["class"] = "lastest", ["has_data"] = has_data});

    local curTypeCount = commentCount[commentType] or 0;
    if #lastestRecords + #topPraiseRecords > curTypeCount then
        -- 更新数量
        commentCount[commentType] = #lastestRecords + #topPraiseRecords;
    end
end

-- 隐藏仅显示本地语言的版本
function hideLocalChange()
    -- 国内的都隐藏
    return not isOverseaPackage();
end

-- 设置指定语言
function setCommentLang(lang)
    commentLang = lang;
end

-- 获取指定语言
function getCommentLang()
    if commentLang and commentLang ~= "" and not hideLocalChange() then
        return commentLang;
    end
    return nil;
end

-- 获取数据
function getAllData()
    -- 直接把所有数据读走
    return table.append(table.deepcopy(topPraiseRecords), table.deepcopy(lastestRecords));
end

-- 获取指定语言的数据
function getAllDataBylang(lang)
    lang = lang or getLang();
    local datas = getAllData();
    local ret = {};
    for _, data in pairs(datas) do
        if not data["lang"] or lang == data["lang"] then
            table.insert(ret, data);
        end
    end
    return ret;
end

-- 评论数量更新
function updateCommentCount(commentType, count)
    if commentCount[commentType] and commentCount[commentType] == count then
        -- 不需要更新
        return;
    end
    commentCount[commentType] = count;

    -- 抛出事件
    EventMgr.fire(event.UPDATE_COMMENT_COUNT, { ["commentType"] = commentType, });
end

-- 获取评论数量
function getCommentCount(commentType)
    local count = commentCount[commentType] or 0;
    return math.min(count, MAX_SHOW_COUNT);
end

-- 检查请求评论数量是否在限制时间内
function canRequestCommentCount(commentType)
    local record = commentCount[commentType];
    if not record then
        -- 没有该数据，可以请求
        return true;
    end

    if not commentCountTime[commentType] or
        TimeM.getServerTime() - commentCountTime[commentType] >=  TIME_LIMIT then
        -- 距离上次请求大于10分钟，可以请求
        return true;
    end

    -- 不允许请求
    return false;
end

-- 设置时间
function setCommentCountTime(commentType)
    commentCountTime[commentType] = TimeM.getServerTime();
end

